package org.magnerfuller.imtoolkit.server.service;

import java.io.*;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * The class ExternalServiceBackend provides a service backend capable of
 * launching an external program as a stream-oriented service.
 *
 */
public class ExternalServiceBackend extends ServiceBackend {

  /** moduleName -- This is the name of the containing module */
  public static final String moduleName = "external";
  
  /** cmdLine -- The command line to be executed for the service */
  private String[] cmdLine;

  /** procBuilder -- For building the process to run */
  private ProcessBuilder procBuilder;

  /** proc -- The running process */
  private Process proc = null;
  
  /**
   * Default constructor
   * 
   * @throws Exception
   */
  public ExternalServiceBackend() throws Exception {
    super();
    
    // This might expand later...
    
  }//ExternalServiceBackend
  
  /**
   * Perform initialization.
   * 
   * @param params -- The parameters for initialization
   * @throws Exception
   */
  public void initialize(Map<String, String> params) throws Exception {
    String args = params.get("args");
    if(args == null) {
      throw new Exception("No args!");
    }
    StringTokenizer tok = new StringTokenizer(args);
    String[] cmd = new String[tok.countTokens()];
    for(int i = 0; tok.hasMoreTokens(); i++) {
      cmd[i] = tok.nextToken();
      i++;
    }
    cmdLine = cmd;
    
    List<String> cmdList = new ArrayList<String>();

    for(int i = 0; i < cmdLine.length; i++) {
      cmdList.add(cmdLine[i]);
    }

    procBuilder = new ProcessBuilder(cmdList);
  }//initialize

  /**
   * Provide the service!
   */
  public void run() {
    try {
      proc = procBuilder.start();
      proc.waitFor();
    } catch(IOException e) {
      System.err.println("ExternalServiceBackend::run: " + e);
    } catch(InterruptedException e) {
      System.err.println("ExternalServiceBackend::run: " + e);
    }
  }//run

  /**
   * Get the input stream.
   * 
   * @return the input stream
   */
  public InputStream getInputStream() {
    return proc == null ? null : proc.getInputStream();
  }//getInputStream

  /**
   * Get the output stream.
   */
  public OutputStream getOutputStream() {
    return proc == null ? null : proc.getOutputStream();
  }//getOutputStream
  
}//ExternalServiceBackend
